/**
 * &copy; 2006 NewInstance.it
 */
package it.newinstance.jrainbow.parser;

import it.newinstance.jrainbow.source.TaggedSource;
import it.newinstance.util.Configuration;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;

/**
 * @author Luigi R. Viggiano
 * @version $Id: Parser.java 159 2007-11-15 02:33:39Z luigi.viggiano $
 */
public interface Parser {

    /**
     * Parse source read from the URL, returning a tagged source.
     * 
     * @param url
     *            the url to the source to parse
     * @return the tagged source resulting from the parse
     * @throws IOException
     */
    public TaggedSource parse(URL url) throws IOException;

    /**
     * Parse source read from the input stream, returning a tagged source.
     * 
     * @param inputStream
     *            the InputStream to the source to parse
     * @return the tagged source resulting from the parse
     * @throws IOException
     */
    public TaggedSource parse(InputStream inputStream) throws IOException;

    /**
     * Parse source read from the reader, returning a tagged source.
     * 
     * @param reader
     *            the reader to the source to parse
     * @return the tagged source resulting from the parse
     * @throws IOException
     */
    public TaggedSource parse(Reader reader) throws IOException;

    /**
     * Parse the given String, returning a tagged source.
     * 
     * @param string
     *            the source to parse
     * @return the tagged source resulting from the parse
     */
    public TaggedSource parse(String string);

    /**
     * Parse the given source, tagging each char.
     * 
     * @param source
     *            the source to parse
     */
    public void parse(TaggedSource source);

    /**
     * @return a descriptive name of the language parsed by the parser
     */
    public String getLanguageName();

    public final static class Factory {
        private static final Configuration conf = Configuration
                .getConfiguration(Parser.class);

        private Factory() {
        }

        /**
         * Return a parser for a given language.
         * 
         * @param language
         *            the language of the wanted parser
         * @return a parser for the given language
         * @throws UnsupportedParserException
         *             when the requested parse could not be created
         */
        @SuppressWarnings("unchecked")
        public static Parser newInstance(String language)
                throws UnsupportedParserException {
            String parserClassName = conf.getString(language);
            try {
                return (Parser) ((Class<Parser>) Class.forName(parserClassName))
                        .newInstance();
            } catch (Exception e) {
                throw new UnsupportedParserException(language, e);
            }
        }
    }
}
